package com.demo.core.dao.impl.base;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import org.springframework.util.Assert;

import com.demo.core.cache.CacheKey;
import com.demo.core.cache.CacheWrapper;
import com.demo.core.dao.base.support.ResultSearchResult;
import com.demo.core.dao.base.support.SearchArgumentAware;
import com.demo.core.dao.base.support.SearchArgumentSupport;
import com.demo.core.dao.base.support.SearchDaoSupport;
import com.demo.core.model.support.SimpleBaseModel;

/**
 * 带有分页查询的数据访问层抽象类
 * 
 * @author ryuu.kk
 * @param <PK>
 * @param <T>
 *
 */
public abstract class PageCoreDaoSupport<T extends SimpleBaseModel, PK extends java.io.Serializable> extends BaseCoreDaoSupport<T, PK> implements SearchDaoSupport<T> {

	@SuppressWarnings("unchecked")
	@Override
	public <E> ResultSearchResult<T> search(Object target, E e,	SearchArgumentSupport args) {
		//代理处理
		Assert.notNull(target);
		Assert.notNull(e);
		
		ResultSearchResult<T> result = null;
		//分解参数
		e = resolve(e, args);
		
		// -------------------------------------------------------------
		// *************   取得分页、排序缓存设置        ***************    
		CacheKey key = null;
		int hashCode = e.hashCode();
		CacheWrapper<CacheKey, Object> cache = null;
		if (isUseCache() && (cache = getCache()) != null) {
			key = new CacheKey();
			// namespace + sqlID + 参数.hashCode
			key.update(nameSpace());
			//key.update("search");
			key.update(target);
			/*
			if (target instanceof String) {
				key.update(target);
			} else {
				key.update(target.hashCode());
			}*/
			key.update(hashCode);
			result = (ResultSearchResult<T> ) cache.get(key);
		}
		if (result != null) {
			return result;
		}
		// -------------------------------------------------------------
		
		//判断目标类型
		if (target instanceof String) {
			result = ((ResultSearchResult<T>) getSqlMapClientTemplate().queryForObject(nameSpace() + target, e));
		}
		if (target instanceof Method) {
			//TODO:Dao层方法的直接调用,未测试 at 2012-03-22.
			try {
				((Method) target).invoke(target, e);
			} catch (IllegalArgumentException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (InvocationTargetException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		// -------------------------------------------------------------
		// *************   设置分页、排序缓存设置        ***************  
		if (isUseCache() && cache != null && result != null) {
			cache.put(key, result);
		}
		// -------------------------------------------------------------
		return result;
	}

	@Override
	public <E> ResultSearchResult<T> search(E e, SearchArgumentSupport args) {
		return search("select", e, args);
	}
	
	/**
	 * 分解分页参数
	 * @param e 检索参数
	 * @param args 分页函数
	 * @return 新的检索参数
	 */
	@SuppressWarnings("unchecked")
	protected <E> E resolve(E e, SearchArgumentSupport args) {
		//如果是Map参数将,将分页参数放入Map参数中
		if (e instanceof Map) {
			((Map<String, Object>) e).put(SearchArgumentSupport.class.getName(), args);
		}
		//如果模型作为参数,将分页参数放入模型对象中
		if (e instanceof SearchArgumentAware) {
			((SearchArgumentAware) e).setPageSupport(args);
		}
		//如果参数实现某一分页接口,将分页参数放入其中
		//do-something
		return e;
	}
}
